/*
 * The spring-based xzixi framework simplifies development.
 *
 * Copyright (C) 2020  xuelingkang@163.com.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package xyz.hellothomas.sftp.client.core;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

/**
 * @author Thomas
 * @date 2022/2/13 14:24
 * @description
 * @version 1.0
 */
public class SftpPooledObjectFactory extends BasePooledObjectFactory<SftpClient> {

    private String host;
    private int port;
    private String username;
    private String password;
    private int connectTimeout;

    public SftpPooledObjectFactory(String host, int port, String username, String password, int connectTimeout) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
        this.connectTimeout = connectTimeout;
    }

    /**
     * 创建一个{@link SftpClient}实例
     * 这个方法必须支持并发多线程调用
     *
     * @return {@link SftpClient}实例
     */
    @Override
    public SftpClient create() {
        return new SftpClient(host, port, username, password, connectTimeout);
    }

    /**
     * 用{@link PooledObject}的实例包装对象
     *
     * @param sftpClient 被包装的对象
     * @return 对象包装器
     */
    @Override
    public PooledObject<SftpClient> wrap(SftpClient sftpClient) {
        return new DefaultPooledObject<>(sftpClient);
    }

    /**
     * 销毁对象
     *
     * @param p 对象包装器
     */
    @Override
    public void destroyObject(PooledObject<SftpClient> p) {
        if (p != null) {
            SftpClient sftpClient = p.getObject();
            if (sftpClient != null) {
                sftpClient.close();
            }
        }
    }

    /**
     * 检查连接是否可用
     *
     * @param p 对象包装器
     * @return {@code true} 可用，{@code false} 不可用
     */
    @Override
    public boolean validateObject(PooledObject<SftpClient> p) {
        if (p != null) {
            SftpClient sftpClient = p.getObject();
            if (sftpClient != null) {
                return sftpClient.test();
            }
        }
        return false;
    }

    public static SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder builder() {
        return new SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder();
    }

    public static class SftpPooledObjectFactoryBuilder {
        private String host;
        private int port;
        private String username;
        private String password;
        private int connectTimeout;

        SftpPooledObjectFactoryBuilder() {
        }

        public SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder host(String host) {
            this.host = host;
            return this;
        }

        public SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder port(int port) {
            this.port = port;
            return this;
        }

        public SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder username(String username) {
            this.username = username;
            return this;
        }

        public SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder password(String password) {
            this.password = password;
            return this;
        }

        public SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder connectTimeout(int connectTimeout) {
            this.connectTimeout = connectTimeout;
            return this;
        }

        public SftpPooledObjectFactory build() {
            return new SftpPooledObjectFactory(this.host, this.port, this.username, this.password, this.connectTimeout);
        }


        @Override
        public String toString() {
            return "SftpPooledObjectFactory.SftpPooledObjectFactoryBuilder(host=" + this.host + ", port=" + this.port + ", username=" + this.username + ", password=" + this.password + ", connectTimeout=" + this.connectTimeout + ")";
        }
    }
}
